const http = require('http');
const fs = require('fs');
const path = require('path');

const targetFile = process.argv[2] 
  ? path.join(__dirname, process.argv[2]) 
  : __filename;

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
  let fileContent = ''; // 用于拼接读取到的文件内容

  // 1. 打开文件：fs.open(path,  flags, callback)
  // 'r' 表示只读模式，若文件不存在则报错
  fs.open(targetFile, 'r', (err, fd) => {
    if (err) {
      const errorMsg = `错误：无法打开文件 "${targetFile}"\n原因：${err.message}`;
      res.end(errorMsg);
      console.error(errorMsg);
      return;
    }
    console.log(`成功打开文件，文件描述符（fd）：${fd}`);

    // 2. 配置读取参数：缓冲区（1024字节）、读取位置、读取长度
    const buffer = Buffer.alloc(1024); // 分配1KB缓冲区
    let offset = 0; // 缓冲区写入起始位置
    let position = 0; // 文件读取起始位置
    const length = buffer.length; // 每次读取的字节数

    // 3. 读取文件：fs.read(fd, buffer, offset, length, position, callback)
    fs.read(fd, buffer, offset, length, position, (err, bytesRead, buffer) => {
      if (err) {
        const errorMsg = `错误：读取文件时失败\n原因：${err.message}`;
        res.end(errorMsg);
        console.error(errorMsg);
        fs.close(fd, () => console.log(`已关闭文件描述符 ${fd}（读取失败后清理）`));
        return;
      }

      // 拼接读取到的内容（注意：只取实际读取到的字节数，避免缓冲区空数据）
      fileContent += buffer.toString('utf8', 0, bytesRead);

      // 4. 关闭文件：读取完成后必须关闭文件描述符，避免资源泄漏
      fs.close(fd, (err) => {
        if (err) {
          const errorMsg = `错误：关闭文件时失败\n原因：${err.message}`;
          res.end(errorMsg);
          console.error(errorMsg);
          return;
        }

        // 5. 响应结果给客户端
        const responseContent = `成功读取文件：${targetFile}\n（通过 open -> read -> close 流程）\n\n文件内容：\n${fileContent}`;
        res.end(responseContent);
        console.log(`已关闭文件描述符 ${fd}，并向客户端响应内容`);
      });
    });
  });
});

server.listen(8081, () => {
  console.log(`服务器已启动，监听端口 8081`);
  console.log(`当前读取目标：${targetFile}`);
  console.log(`请访问：http://localhost:8081 查看结果`);
});